package cc.magicjson.data.operation.router.db.executor;

import cc.magicjson.data.operation.router.db.exception.DatabaseOperationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;

@Slf4j
@Component
public class EntityOperationExecutor {

    public <T> T executeWrite(T entity, List<DataSource> dataSources,
                             BiFunction<DataSource, T, T> operation) throws DatabaseOperationException {
        T result = null;
        List<Exception> exceptions = new ArrayList<>();

        for (DataSource ds : dataSources) {
            try {
                result = operation.apply(ds, entity);
            } catch (Exception e) {
                exceptions.add(e);
                log.error("Failed to execute write operation on datasource: " + ds, e);
            }
        }

        if (!exceptions.isEmpty() && exceptions.size() == dataSources.size()) {
            throw new DatabaseOperationException("All write operations failed", exceptions);
        }

        return result;
    }
}
